package cn.buk.qms.service;

import cn.buk.common.JsonResult;
import cn.buk.common.sc.CommonSearchCriteria;
import cn.buk.tms.dto.AirlinesDto;
import cn.buk.tms.dto.AirportDto;
import cn.buk.tms.dto.CityDto;
import cn.buk.tms.dto.FlightCondTimeWindowDto;
import cn.buk.tms.entity.base.Airline;
import cn.buk.tms.entity.base.Airport;
import cn.buk.tms.entity.base.City;
import cn.buk.tms.entity.misc.*;
import cn.buk.tms.flight.dto.LuggageInfoDto;
import cn.buk.tms.util.ValidationUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author yfdai
 */
@Service
public class BasicDataServiceImpl extends BaseAbstractService implements BasicDataService {

    @Override
    public List<Airline> searchAirlineInfo(String twoCode) {
        if (twoCode == null || twoCode.length() != 2) {
          return basicDataDao.getAllAirlines();
        } else {
          return basicDataDao.searchAirlines(twoCode);
        }
    }

    @Override
    public JsonResult saveAirlineInfo(int enterpriseId, Airline airline) {
        JsonResult jsonResult = new JsonResult();

        if (enterpriseId != Enterprise.ENTERPRISE_PLATFORM_ADMINISTRATOR) {
          return jsonResult;
        }

        int retCode = basicDataDao.saveAirline(airline);
        if (retCode > 0) {
            jsonResult.setStatus("OK");
        }

        return jsonResult;
    }

    @Override
    public List<FareCondition> searchFareCondition(int enterpriseId, String carrier, String subclass) {
        List<FareCondition> results = null;
        if (enterpriseId != Enterprise.ENTERPRISE_PLATFORM_ADMINISTRATOR) {
            results = basicDataDao.searchFareCondition(enterpriseId, carrier, subclass);
        }

        if (results == null || results.isEmpty()) {
            results = basicDataDao.searchFareCondition(0, carrier, subclass);
        }

        return results;
    }

    @Override
    public List<Airport> searchAirports() {
        return basicDataDao.searchAirport(null);
    }

    @Override
    public List<Airport> searchAirportsByCountryCode(String countryCode) {
        return basicDataDao.searchAirportsByCountry(countryCode);
    }

    @Override
    public List<AirportDto> searchAirports(int enterpriseId, CommonSearchCriteria sc) {
        List<Airport> airports = basicDataDao.searchAirports(sc);
        List<AirportDto> dtos = new ArrayList<>();

        for(Airport airport: airports) {
            dtos.add(AirportDto.createBy(airport));
        }

        return dtos;
    }

    @Override
    public Airport getAirportByCode(String threeCode) {
        return basicDataDao.getAirport(threeCode);
    }

    @Override
    @Secured({RoleInfo.ROLE_ADMIN, RoleInfo.ROLE_DATA_ADMIN})
    public JsonResult createAirport(int enterpriseId, AirportDto dto) {
        try {
            ValidationUtils.validate(dto);
        } catch (RuntimeException ex) {
            return JsonResult.createJsonResult(-1, ex.getMessage());
        }

        if (this.getOwnerId() == 0 || this.getOwnerId() != enterpriseId) {
            throw new RuntimeException("未获授权维护机场静态数据");
        }

        int retCode = 0;
        String errmsg = null;

        Airport airport = AirportDto.convertTo(dto);
        try {
            retCode = basicDataDao.createAirport(airport);
        } catch (RuntimeException ex) {
            //试试更新
            retCode = basicDataDao.updateAirport(airport);
            errmsg = "";
        }

        return JsonResult.createJsonResult(retCode, errmsg);
    }

    @Override
    public List<CityDto> searchCities(int enterpriseId, CommonSearchCriteria sc) {
        List<City> cities = basicDataDao.searchCities(sc);
        List<CityDto> dtos = new ArrayList<>();

        for(City city: cities) {
            dtos.add(CityDto.createdBy(city));
        }

        return dtos;
    }

    @Override
    @Secured({RoleInfo.ROLE_ADMIN, RoleInfo.ROLE_DATA_ADMIN})
    public JsonResult createCity(final int enterpriseId, final String username, CityDto dto) {
        try {
            ValidationUtils.validate(dto);
        } catch (RuntimeException ex) {
            return JsonResult.createJsonResult(-1, ex.getMessage());
        }

        if (this.getOwnerId() == 0 || this.getOwnerId() != enterpriseId) {
            throw new RuntimeException("未获授权维护城市静态数据");
        }

        int retCode = 0;
        String errmsg = null;

        City city = CityDto.convertTo(dto);
        try {
            retCode = basicDataDao.createCity(enterpriseId, username, city);
        } catch (RuntimeException ex) {
            retCode = -100;
            errmsg = ex.getMessage();
        }

        return JsonResult.createJsonResult(retCode, errmsg);
    }


    @Override
    @Secured({RoleInfo.ROLE_ADMIN, RoleInfo.ROLE_DATA_ADMIN})
    public JsonResult createAirlines(int enterpriseId, AirlinesDto dto) {
        if (this.getOwnerId() == 0 || this.getOwnerId() != enterpriseId) {
            throw new RuntimeException("未获授权维护航空公司静态数据");
        }

        try {
            ValidationUtils.validate(dto);
        } catch (RuntimeException ex) {
            return JsonResult.createJsonResult(-1, ex.getMessage());
        }

        Airline airlines = AirlinesDto.convertTo(dto);

        if (airlines.getId() > 0) {
            int retcode = basicDataDao.updateAirlines(airlines);
            return JsonResult.createJsonResult(retcode);
        } else {
            try {
                int retCode = basicDataDao.createAirlines(airlines);
                return JsonResult.createJsonResult(retCode);
            } catch (RuntimeException ex) {
                return JsonResult.createJsonResult(-100, ex.getMessage());
            }
        }
    }

  @Override
  @Secured({RoleInfo.ROLE_ADMIN, RoleInfo.ROLE_DATA_ADMIN})
  public JsonResult saveLuggageInfo(int enterpriseId, LuggageInfoDto dto) {
      try {
          ValidationUtils.validate(dto);
      } catch (RuntimeException ex) {
          return JsonResult.createJsonResult(-1, ex.getMessage());
      }

      LuggageInfo info = new LuggageInfo();
      BeanUtils.copyProperties(dto, info);

      info.setEnterpriseId(enterpriseId);
      try {
          int retCode = basicDataDao.saveLuggageInfo(info);
          return JsonResult.createJsonResult(retCode);
      } catch (RuntimeException ex) {
          return JsonResult.createJsonResult(-100, ex.getMessage());
      }
  }

  @Override
  public List<LuggageInfoDto> searchLuggageInfos(int enterpriseId, CommonSearchCriteria sc) {
      if (sc == null) {
          return new ArrayList<>();
      }

      List<LuggageInfo> list = basicDataDao.searchLuggageInfos(enterpriseId, sc);

      List<LuggageInfoDto> dtos = new ArrayList<>();
      for(LuggageInfo info: list) {
          LuggageInfoDto dto = new LuggageInfoDto();
          BeanUtils.copyProperties(info, dto);

          dtos.add(dto);
      }

      return dtos;
  }

  @Override
  public LuggageInfoDto searchLuggageInfo(int enterpriseId, int id) {
      LuggageInfo info = basicDataDao.getLuggageInfoById(id);
      if (info == null) {
          return null;
      }

      LuggageInfoDto dto = new LuggageInfoDto();
      BeanUtils.copyProperties(info, dto);

      return dto;
  }

  @Override
  public List<FlightCondTimeWindowDto> searchFlightConditionTimeWindows(String carrier) {
      List<FlightConditionTimeWindow> list = basicDataDao.searchFlightConditionTimeWindows(carrier);

      if (list.isEmpty()) {
          //设置默认
          FlightConditionTimeWindow timeWindow =
                  createFlightConditionTimeWindow(carrier, 1, 0, 0, 7*24, 0);
          list.add(timeWindow);

          timeWindow = createFlightConditionTimeWindow(carrier, 2, 7*24, 1, 2*24, 0);
          list.add(timeWindow);

          timeWindow = createFlightConditionTimeWindow(carrier, 3, 2*24, 1, 4, 0);
          list.add(timeWindow);

          timeWindow = createFlightConditionTimeWindow(carrier, 4, 4, 1, 0, 0);
          list.add(timeWindow);
      }

      List<FlightCondTimeWindowDto> dtos = new ArrayList<>();
      for(FlightConditionTimeWindow o: list) {
          dtos.add(FlightCondTimeWindowDto.createdBy(o));
      }

      return dtos;
  }

    @Override
    @Secured({RoleInfo.ROLE_DATA_ADMIN, RoleInfo.ROLE_ADMIN})
    public JsonResult saveFlightConditionTimeWindows(final int userId, List<FlightCondTimeWindowDto> timeWindowDtos) {
        User user = userDao.getUserById(userId);
        if (user.getEnterpriseId() != getOwnerId()) {
            throw new RuntimeException("You have not privileges.");
        }

        //TODO 校验时间设置是否正确
        if (timeWindowDtos.size() != 4) {
            throw new RuntimeException("There should be 4 time frames.");
        }

        //一个航司
        final String carrier = timeWindowDtos.get(0).getCarrier();
        List<FlightConditionTimeWindow> timeWindows = new ArrayList<>();
        for(FlightCondTimeWindowDto dto: timeWindowDtos) {
            FlightConditionTimeWindow timeWindow = new FlightConditionTimeWindow();
            BeanUtils.copyProperties(dto, timeWindow);
            timeWindows.add(timeWindow);
        }

        int retCode = basicDataDao.saveFlightConditionTimeWindows(userId, carrier, timeWindows);

        return JsonResult.createJsonResult(retCode);
    }


    private FlightConditionTimeWindow createFlightConditionTimeWindow(String carrier,
                                                                      int orderNo, int maxHours, int maxIncluded, int minHours, int minIncluded) {
        FlightConditionTimeWindow timeWindow = new FlightConditionTimeWindow();
        timeWindow.setCarrier(carrier);
        timeWindow.setWindowOrder(orderNo);

        timeWindow.setMaxHours(maxHours);
        timeWindow.setMaxIncluded(maxIncluded);

        timeWindow.setMinHours(minHours);
        timeWindow.setMinIncluded(minIncluded);

        return timeWindow;
    }

}
